package com.hqd.ch03.v34.web.servlet.mvc;

import com.hqd.ch03.v34.web.http.HttpMethod;
import com.hqd.ch03.v34.web.servlet.support.WebContentGenerator;
import com.hqd.ch03.v34.web.utils.WebUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public abstract class AbstractController extends WebContentGenerator implements Controller {

    private boolean synchronizeOnSession = false;

    public AbstractController() {
        this(true);
    }

    public AbstractController(boolean restrictDefaultSupportedMethods) {
        super(restrictDefaultSupportedMethods);
    }

    public final boolean isSynchronizeOnSession() {
        return this.synchronizeOnSession;
    }

    public final void setSynchronizeOnSession(boolean synchronizeOnSession) {
        this.synchronizeOnSession = synchronizeOnSession;
    }

    @Override
    public String handleRequest(HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        if (HttpMethod.OPTIONS.matches(request.getMethod())) {
            response.setHeader("Allow", getAllowHeader());
            return null;
        }
        checkRequest(request);
        prepareResponse(response);
        /**
         * session安全，必须同步
         */
        if (this.synchronizeOnSession) {
            HttpSession session = request.getSession(false);
            if (session != null) {
                Object mutex = WebUtils.getSessionMutex(session);
                synchronized (mutex) {
                    return handleRequestInternal(request, response);
                }
            }
        }

        return handleRequestInternal(request, response);
    }

    protected abstract String handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
            throws Exception;

}